package org.example;

import cn.hutool.core.io.FileUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import org.apache.commons.lang.StringEscapeUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ParseXmlUtil {
    public void getNodes(Element node) {
        System.out.println("--------------------");

        //当前节点的名称、文本内容和属性
        System.out.println("当前节点名称：" + node.getName());//当前节点名称
        System.out.println("当前节点的内容：" + node.getTextTrim());//当前节点名称
        List<Attribute> listAttr = node.attributes();//当前节点的所有属性的list
        for (Attribute attr : listAttr) {//遍历当前节点的所有属性
            String name = attr.getName();//属性名称
            String value = attr.getValue();//属性的值
            System.out.println("属性名称：" + name + "属性值：" + value);
        }

        //递归遍历当前节点所有的子节点
        List<Element> listElement = node.elements();//所有一级子节点的list
        for (Element e : listElement) {//遍历所有一级子节点
            this.getNodes(e);//递归
        }
    }

    public static Map<String, String> getTxnCodeMap(String excelPath) {
        Map<String, String> txnCodeMap = new HashMap<>();

        ExcelReader reader = ExcelUtil.getReader(excelPath);
        List<List<Object>> lines = reader.read();

        for (int i = 1; i < lines.size(); i++) {
            List<Object> line = lines.get(i);
            String srcCode = line.get(0).toString();
            String targetCode = line.get(1).toString();
            txnCodeMap.put(srcCode, targetCode);
        }

        return txnCodeMap;
    }

    public static Element getElement(Element rootElement, String attrId, String attrValue) {

        //递归遍历当前节点所有的子节点
        List<Element> listElement = rootElement.elements();//所有一级子节点的list
        for (Element e : listElement) {//遍历所有一级子节点
            List<Attribute> attributes = e.attributes();
            for (Attribute attr : attributes) {//遍历当前节点的所有属性
                String name = attr.getName();//属性名称
                String value = attr.getValue();//属性的值
                if (name.equals(attrId) && value.equals(attrValue)) {
                    return e;
                }
            }
        }

        return null;
    }

    public static void replaceCommCode(Map<String, String> txnCodeMap, String dir) throws DocumentException, IOException {

        // 获得指定目录下所有流程文件
        List<File> files = FileUtil.loopFiles(dir, file -> file.getName().endsWith("tfml"));

        // 遍历所有流程文件进行处理
        for (File file : files) {
            String fileName = file.getName();

            // 根据流程文件名获取该交易的通讯码（即去掉模块名）
            String regEx = "[^0-9]";
            Pattern p = Pattern.compile(regEx);
            Matcher m = p.matcher(fileName);
            String commCode = m.replaceAll("").trim();

            // 获取该通讯码需要替换的新通讯码（来源于指定的excel）
            String replaceCode = txnCodeMap.get(commCode);

            // 若excel中不存在替换通讯码则处理下一个文件
            if (replaceCode == null) {
                continue;
            }

            System.out.println("开始处理文件:" + fileName);

            // 读取xml文件
            Document doc = new SAXReader().read(file);

            // 获取根节点
            Element rootElement = doc.getRootElement();

            // 获取通讯码配置节点并修改其值
            Element commElem= getElement(rootElement, "id", "INVOKEROUTE8"); // 获取通讯node节点
            Element parameterElem = getElement(commElem, "name", "submitTaskId"); // 获取通讯node节点的参数配置节点
            List<Attribute> listAttr = parameterElem.attributes();//当前节点的所有属性的list
            for (Attribute attr : listAttr) {//遍历当前节点的所有属性
                String name = attr.getName();//属性名称
                String value = attr.getValue();//属性的值
                if (name.equals("value")) {
                    // 替换通讯码
                    String newValue = StringEscapeUtils.unescapeHtml("&quot;" + replaceCode + "&quot;");
                    System.out.println("原通讯码：" + value);
                    System.out.println("新通讯码：" + newValue);
                    attr.setValue(newValue);
                }
            }

            // 将结果保存
            XMLWriter writer = new XMLWriter(Files.newOutputStream(file.toPath()));
            writer.write(doc);
            writer.close();
        }


    }

    public static void doReplaceCommCode(String excelPath, String txnDir) throws DocumentException, IOException {

        Map<String, String> txnCodeMap = getTxnCodeMap(excelPath);

        replaceCommCode(txnCodeMap, txnDir);

        System.out.println("处理完成");
    }
}
